/*
 * @Author: lp
 * @Date: 2022-01-07 13:49:35
 * @LastEditTime: 2022-06-22 13:45:14
 * @LastEditors: lp 654528967@qq.com
 * @Description: 封装axios请求
 * @FilePath: \nien-vue3-admin\src\utils\request.ts
 */
import axios, { AxiosRequestConfig, Method, AxiosError, AxiosInstance } from 'axios'
import { ElMessageBox, ElMessage } from 'element-plus'
import { getToken, getTokenType } from '@/utils/auth'
import userStore from '@/store/modules/user'
// import{tansParams} from "@utils/index";

// import {ElLoadingComponent } from 'element-plus/dist/types/loading.vue'
interface PendingType {
  url?: string;
  method?: Method;
  params?: object;
  data?: object;
  // eslint-disable-next-line no-unused-vars
  cancel: (v:string)=>void;
}

// 取消重复请求
const pending: Array<PendingType> = []
const CancelToken = axios.CancelToken
interface newInstance extends AxiosInstance {
  <T = any>(config: AxiosRequestConfig): Promise<T>;
  request<T = any>(config: AxiosRequestConfig): Promise<T>;
  get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
  head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
  patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
}
const instance: newInstance = axios.create({
  baseURL: import.meta.env.VITE_BASE_API as any,
  timeout: 1000 * 60,
  headers: { 'Content-Type': 'application/json;charset=utf-8' },
})
const removePending = (config: AxiosRequestConfig) => {
  for (const key in pending) {
    const item: number = +key
    const list: PendingType = pending[item]
    if (list.url === config.url && list.method === config.method && JSON.stringify(list.params) === JSON.stringify(config.params) && JSON.stringify(config.data) === JSON.stringify(list.data)) {
      list.cancel('操作太频繁，请稍后再试')
      pending.splice(item, 1)
    }
  }
}
instance.interceptors.request.use(
  (req: any): AxiosRequestConfig => {
    const token = getToken()
    const tokenType = getTokenType()
    if (token !== null && token !== undefined && token !== '') {
      req.headers.Authorization = `${ tokenType } ${ token }`
    }
    removePending(req)
    // const {url}
    req.cancelToken = new CancelToken((c) => pending.push({ ...req, cancel: c }))
    
    return req
  },
)
instance.interceptors.response.use(
  (res: any): Promise<any> => {
    const code = res.data.code || 200
    if (code === 401) {
      ElMessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(async () => {
        const user = userStore()
        await user.clearToken()
        window.location.reload() // 为了重新实例化vue-router对象 避免bug
      })
      .catch((err) => {
        ElMessage.error(err)
      })
      return Promise.reject(res.data)
    } if (code === 500) {
      const msg = res.data.msg || '系统未知错误'
      ElMessage.error(msg)
      return Promise.reject(res.data)
    }

    return Promise.resolve(res.data)
  },
  (err: AxiosError) => {
    console.log(err)
    return Promise.reject(err)
  },
)

// 通用下载方法
// export function download(url, params, filename) {
//   return instance
//     .post(url, params, {
//       transformRequest: [
//         params => {
//           return tansParams(params);
//         },
//       ],
//       responseType: "blob",
//     })
//     .then(data => {
//       const content = data;
//       const blob = new Blob([content]);
//       if ("download" in document.createElement("a")) {
//         const elink = document.createElement("a");
//         elink.download = filename;
//         elink.style.display = "none";
//         elink.href = URL.createObjectURL(blob);
//         document.body.appendChild(elink);
//         elink.click();
//         URL.revokeObjectURL(elink.href);
//         document.body.removeChild(elink);
//       } else {
//         navigator.msSaveBlob(blob, filename);
//       }
//     })
//     .catch(r => {
//       console.error(r);
//     });
// }
export default instance
